package prototype;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.util.Arrays;
import java.util.List;

public class CodemeterWindow {

    private JTable metricsTable;
    private JPanel rootPanel;
    private JTextField dbConnectionString;
    private JList modulesList;
    private JList metricsList;
    private JList revisionsList;
    MetricsManagerStub metricsManager = new MetricsManagerStub();
    ListSelectionListener listSelectionListener = new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent e) {
            updateResult();
        }
    };

    public static void main(String[] args) {
        JFrame frame = new JFrame("Codemeter prototype");
        frame.setLocationByPlatform(true);
        CodemeterWindow cw = new CodemeterWindow();
        frame.setContentPane(cw.rootPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cw.updateParameters();
        frame.setVisible(true);
        frame.pack();
    }

    public CodemeterWindow() {
        modulesList.addListSelectionListener(listSelectionListener);
        metricsList.addListSelectionListener(listSelectionListener);
        revisionsList.addListSelectionListener(listSelectionListener);
        rootPanel.setPreferredSize(new Dimension(640, 480));
    }

    void updateParameters() {
        updateMetrics();
        updateModules();
        updateRevisions();
    }

    void updateModules() {
        updateJList(modulesList, metricsManager.allModules());
    }

    void updateMetrics() {
        updateJList(metricsList, metricsManager.allMetrics());
    }

    void updateRevisions() {
        updateJList(revisionsList, metricsManager.allRevisions());
    }

    void updateJList(JList jl, List l) {
        jl.setModel(jListModelFromList(l));
    }

    ListModel jListModelFromList(List l) {
        DefaultListModel res = new DefaultListModel();
        for (Object el : l) res.addElement(el);
        return res;
    }

    void updateResult() {
        metricsTable.setModel(metricsTableModel(
                selectedModules(), selectedRevisions(), selectedMetrics(),
                metricsManager.calculatedMetrics(selectedModules(), selectedRevisions(), selectedMetrics())));
    }

    TableModel metricsTableModel(List modules, List revisions, List metrics, Object[][][] metricsValues) {
        Object[] columns = new Object[2 + metrics.size()];
        columns[0] = "Module";
        columns[1] = "Revision";
        for (int i = 0; i < metrics.size(); i++)
            columns[2 + i] = metrics.get(i);
        Object[][] data = new Object[modules.size() * revisions.size()][2 + metrics.size()];
        for (int i = 0; i < modules.size(); i++) {
            for (int j = 0; j < revisions.size(); j++) {
                Object row[] = data[i * revisions.size() + j];
                row[0] = modules.get(i);
                row[1] = revisions.get(j);
                for (int k = 0; k < metrics.size(); k++) {
                    row[2 + k] = metricsValues[i][j][k];
                }
            }
        }
        return new DefaultTableModel(data, columns);
    }

    List selectedRevisions() {
        return selectedObjects(revisionsList);
    }

    List selectedModules() {
        return selectedObjects(modulesList);
    }

    List selectedMetrics() {
        return selectedObjects(metricsList);
    }

    List selectedObjects(JList jl) {
        return Arrays.asList(jl.getSelectedValues());
    }
}
